feat(build): add system CA root mode - #2324
Conversation
Allow distro builds to use native trust stores for supervisor upstream TLS while keeping bundled Mozilla roots as the default. Avoid bundled root crates in system-ca-roots builds by using native-root TLS features and z3 0.20. Signed-off-by: Adam Miller <admiller@redhat.com>
The telemetry-off task uses --no-default-features which now disables bundled-ca-roots in addition to telemetry, triggering the compile_error guard. Re-enable bundled-ca-roots explicitly so the task verifies only telemetry compilation. Signed-off-by: Scott Burdine <sburdine@nvidia.com> Signed-off-by: politerealism <burdcat17@gmail.com>
|
Thank you for your interest in contributing to OpenShell, @politerealism. This project uses a vouch system for first-time contributors. Before submitting a pull request, you need to be vouched by a maintainer. To get vouched:
See CONTRIBUTING.md for details. |
|
All contributors have signed the DCO ✍️ ✅ |
|
I have read the DCO document and I hereby sign the DCO. |
|
recheck |
|
/ok to test 00c9b14 |
Resolve conflicts in Cargo.lock and crates/openshell-sandbox/Cargo.toml. Keep default-features = false on openshell-supervisor-network while adding new middleware dependencies from main. Signed-off-by: Scott Burdine <sburdine@nvidia.com> Signed-off-by: politerealism <burdcat17@gmail.com>
|
@TaylorMutch @derekwaynecarr or others, can I get an Okay to test and review? I'm working on getting the MR for Hummingbird to work with Openshell and I think this PR will get it working. |
|
/ok to test b454e32 |
The bare `oauth2 = "5"` dependency re-enabled default features (rustls-tls → reqwest/rustls-tls → webpki-roots), defeating the system-ca-roots feature gate. Mirror the CLI fix: disable defaults and enable only the `reqwest` feature. Signed-off-by: Quinn Burdine <sburdine@redhat.com> Signed-off-by: politerealism <burdcat17@gmail.com>
|
/ok to test dea4d85 |
|
@politerealism could you comment on why we elected for a compile-time decision instead of runtime selection? |
|
Yes! @elezar , there are two reasons why it made sense to use compile-time decision instead of runtime selection. If it were runtime, webpki-roots would still be compiled in and linked. A distro packager can't certify a binary that ships it's own trust store alongside the system. The compile_error! guard makes this auditable. Cargo tree proves the dependency is physically absent. |
Replace mutually exclusive bundled-ca-roots / system-ca-roots features with a single bundled-ca-roots toggle. Disabling it implies system roots via rustls-native-certs, which is now a regular (non-optional) dependency. This fixes cargo --all-features and simplifies the distro build interface from --no-default-features --features system-ca-roots to just --no-default-features. Signed-off-by: Quinn Burdine <sburdine@redhat.com> Signed-off-by: politerealism <burdcat17@gmail.com>
| description = "Verify system-ca-roots build compiles and excludes bundled Mozilla root crates" | ||
| run = [ | ||
| # Check that the workspace compiles cleanly without bundled CA roots. | ||
| "cargo check --workspace --all-targets --no-default-features", |
There was a problem hiding this comment.
We should strictly speaking add --features telemetry here to get the behaviour of the build only excluding the bundled-ca-roots.
| ] | ||
|
|
||
| ["rust:verify:system-ca-roots"] | ||
| description = "Verify system-ca-roots build compiles and excludes bundled Mozilla root crates" |
There was a problem hiding this comment.
nit: We no longer have a system-ca-roots build.
|
One concern with the current shape is that "system CA mode" is expressed as bare Two options I see here: Firstly, we introduce named feature-set aliases instead, e.g. cargo build -p openshell-sandbox --no-default-features --features default-system-ca-rootsThat still preserves the core guarantee that the system-root artifact is compiled without bundled roots, but makes the build intent explicit and less fragile. An alternative would be to flip the default. That is to say, by default we build binaries WITHTOUT the In the longer term, if we want upstream packages to ship both variants, the gateway could select between two prebuilt supervisor artifacts at startup. That should remain artifact selection, not a runtime switch inside one binary, so distro packages that prohibit bundled roots can still ship only the system-root artifact. |
|
One wording/design note: the PR currently describes this as adding Could we make that terminology consistent across the PR description/docs/CI labels? I think the clean framing is:
I do not think a feature alias is a blocker here as long as every |
Add a system-ca-roots feature alias on openshell-sandbox that includes all other defaults (telemetry) except bundled-ca-roots, so distro builds can use --no-default-features --features system-ca-roots without manually re-adding unrelated defaults. Update the verify CI task to use the alias and scope checks to the sandbox package. Fix task description to use "build mode" terminology instead of implying a Cargo feature. Signed-off-by: Quinn Burdine <sburdine@redhat.com> Signed-off-by: politerealism <burdcat17@gmail.com>
Signed-off-by: Quinn Burdine <sburdine@redhat.com> Signed-off-by: politerealism <burdcat17@gmail.com>
| ## Convenience alias: all defaults except bundled CA roots. Use | ||
| ## `--no-default-features --features system-ca-roots` to build a supervisor | ||
| ## that uses the platform trust store with telemetry intact. | ||
| system-ca-roots = ["telemetry"] |
There was a problem hiding this comment.
Nit: move closer to default so that it's simpler to see the diff.
There was a problem hiding this comment.
default = ["telemetry", "bundled-ca-roots"]
## Convenience alias for the default sandbox behavior except bundled CA roots.
## Use with `--no-default-features --features system-ca-roots`.
system-ca-roots = ["telemetry"]
telemetry = ["openshell-core/telemetry"]
bundled-ca-roots = ["openshell-supervisor-network/bundled-ca-roots"]
| hyper-util = { workspace = true } | ||
| miette = { workspace = true } | ||
| oauth2 = "5" | ||
| oauth2 = { version = "5", default-features = false, features = ["reqwest"] } |
There was a problem hiding this comment.
Question: (I haven't checked the diff / PR history) Could you comment on why this change was made?
There was a problem hiding this comment.
"The local oauth2 manifest confirms its defaults include rustls-tls, which maps to reqwest/rustls-tls; that’s the bundled-root leak."
There was a problem hiding this comment.
The oauth2 crate's default features include rustls which pulls in reqwest/rustls-tls-webpki-roots, that drags webpki-roots back into the dependency tree even when bundled-ca-roots is disabled. By setting default-features = false and only enabling reqwest, oauth2 inherits the workspace level configuration which uses rustls-tls-native-roots instead.
Without this fix, cargo tree -i webpki-roots --no-default-features --features system-ca-roots would still find webpki roots in the graph, making the whole feature flag pointless and would also negate my previous fix on it.
|
/ok-to-test fe2171d |
…ar default Signed-off-by: Quinn Burdine <sburdine@redhat.com> Signed-off-by: politerealism <burdcat17@gmail.com>
Summary
bundled-ca-rootsCargo feature (default on) toopenshell-supervisor-networkandopenshell-sandbox, allowing Linux distribution builds to use the platform trust store instead of bundled Mozilla roots by building without this featuresystem-ca-rootsconvenience feature alias onopenshell-sandboxthat includes all other defaults (telemetry) except bundled CA roots, so distro builds can use--no-default-features --features system-ca-rootswithout manually re-adding unrelated defaultsrustls-native-certsa regular (non-optional) dependency — whenbundled-ca-rootsis absent, the platform trust store is used automaticallyrustls-tls-native-roots,tls-rustls-ring-native-roots) so RPM-built binaries respect the system trust store without feature flagsrust:verify:telemetry-offCI task to explicitly re-enablebundled-ca-rootswhen disabling default featuresRelated Issue
Enables downstream RPM packaging (https://gitlab.com/redhat/hummingbird/rpms/-/merge_requests/2503) to build against system CA roots.
Design
bundled-ca-rootsis a Cargo feature. "System CA roots" is a build mode selected by building withoutbundled-ca-roots. There is nosystem-ca-rootsfeature onopenshell-supervisor-network— the#[cfg(not(feature = "bundled-ca-roots"))]code path usesrustls-native-certsto read from the platform trust store.The
system-ca-rootsalias onopenshell-sandboxis a convenience feature that includestelemetry(and any future non-CA defaults) so distro package recipes don't need to track unrelated feature additions:Compile-time decision rather than runtime because: (1) a distro auditor needs
cargo treeproof that bundled roots aren't linked, (2) the supervisor binary is injected into containers with no config surface, and (3) the compile-time guard caught webpki-roots leaking back through transitive dependencies that a runtime flag never would have.Changes
crates/openshell-supervisor-network/Cargo.toml: Makewebpki-rootsoptional behindbundled-ca-roots(default); makerustls-native-certsa regular dependencycrates/openshell-supervisor-network/src/l7/tls.rs: Use#[cfg(feature = "bundled-ca-roots")]/#[cfg(not(feature = "bundled-ca-roots"))]to select CA root sourcecrates/openshell-sandbox/Cargo.toml: Forwardbundled-ca-rootsto supervisor-network; addsystem-ca-rootsconvenience alias; setdefault-features = falseon the dependencytasks/rust.toml: Updaterust:verify:system-ca-rootsto use the alias; fixrust:verify:telemetry-offto pass--features bundled-ca-rootsCargo.toml: Addrustls-native-certsto workspace dependencies; switchreqwest,sqlx,kubeto native root variantscrates/openshell-sdk/Cargo.toml: Disable oauth2 default features to prevent webpki-roots leaking back through oauth2's rustls-tls default feature.github/workflows/branch-checks.yml: Update step name to use "build mode" terminologyarchitecture/build.md: Document the single-toggle model and aliasTesting
mise run rust:verify:telemetry-offpasses (telemetry compiled out, CA root guard satisfied)mise run rust:verify:system-ca-rootspasses (system CA roots mode compiles, no webpki-roots in dep tree)cargo test -p openshell-supervisor-networkpasses under default featurescargo check --all-featurespasses (no mutual exclusion conflict)cargo build --release --bin openshell --bin openshell-gateway) builds without feature flagsChecklist
cargo --all-featuresworks